package site.wuao.simplerxjava.operator;

import android.util.Log;

import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func2;
import rx.schedulers.Schedulers;

/**
 * 操作符 - 组合
 *
 * @author wuao
 * @date 2017/12/1
 * @github {https://github.com/CoderWuao}
 * @blogs {http://wuao.site/}
 * @note -
 * ---------------------------------------------------------------------------------------------------------------------
 * @modified -
 * @date -
 * @github -
 * @blogs -
 * @note -
 */
public class GroupOperator {
    /** 标记 */
    private static final String TAG = "GroupOperator";

    /**
     * startWith
     *
     * @note 在源Observable发射的数据前面插入一些数据
     */
    public void startWith() {
        Observable
                .just(1, 2, 3, 4, 5)
                .startWith(6, 7)
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        Log.i(TAG, "call: " + integer);
                    }
                });

        // call: 6
        // call: 7
        // call: 1
        // call: 2
        // call: 3
        // call: 4
        // call: 5
    }

    /**
     * merge - 合并
     *
     * @note 1.将多个Observable合并到一个Observable中进行发射
     * 2.可能会让合并的Observable发射的数据交错
     */
    public void merge() {
        Observable<Integer> observable1 = Observable
                .just(1, 2, 3)
                .subscribeOn(Schedulers.io());

        Observable<Integer> observable2 = Observable
                .just(4, 5, 6);

        Observable
                .merge(observable1, observable2)
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        Log.i(TAG, "call: " + integer);
                    }
                });

        // call: 4
        // call: 5
        // call: 6
        // call: 1
        // call: 2
        // call: 3
    }

    /**
     * concat - 合并
     *
     * @note 1.将多个Observable合并到一个Observable中进行发射
     * 2.严格按照顺序发射数据
     * 3.第一个Observable没有发射完是不会发射后一个Observable的数据的
     */
    public void concat() {
        Observable<Integer> observable1 = Observable
                .just(1, 2, 3)
                .subscribeOn(Schedulers.io());

        Observable<Integer> observable2 = Observable
                .just(4, 5, 6);

        Observable
                .concat(observable1, observable2)
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        Log.i(TAG, "call: " + integer);
                    }
                });

        // call: 1
        // call: 2
        // call: 3
        // call: 4
        // call: 5
        // call: 6
    }

    /**
     * zip
     *
     * @note 合并两个或者多个Observable发射出的数据项，根据指定函数变换他们，并发射一个新值
     */
    public void zip() {
        Observable<Integer> observable1 = Observable
                .just(1, 2, 3);

        Observable<Integer> observable2 = Observable
                .just(4, 5, 6);

        Observable
                .zip(observable1, observable2, new Func2<Integer, Integer, Integer>() {
                    @Override
                    public Integer call(Integer integer, Integer integer2) {
                        return integer + integer2;
                    }
                })
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        Log.i(TAG, "call: " + integer);
                    }
                });

        // call: 5
        // call: 7
        // call: 9
    }

    /**
     * combineLatest
     */
    public void combineLatest() {
        Observable<Integer> observable1 = Observable
                .just(1, 2, 3);

        Observable<Integer> observable2 = Observable
                .just(4, 5, 6);

        Observable
                .combineLatest(observable1, observable2, new Func2<Integer, Integer, Integer>() {
                    @Override
                    public Integer call(Integer integer, Integer integer2) {
                        return integer + integer2;
                    }
                })
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        Log.i(TAG, "call: " + integer);
                    }
                });

        // call: 7
        // call: 8
        // call: 9
    }
}
